home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / security / doc / clippings / 930610-02 < prev    next >
Encoding:
Text File  |  1993-07-10  |  11.3 KB  |  274 lines

  1. Subject: more expreserve nonsense
  2. Date: Thu, 10 Jun 93 09:03:29 +0200
  3. From: Christopher Lott <lott@informatik.uni-kl.de>
  4. Message-Id:  <9306100903.aa19612@chanel.informatik.uni-kl.de>
  5.  
  6.  
  7. Hi,
  8.  
  9. The latest is that Sun has released a patch for expreserve in SunOS 4. 
  10. Unfortunately, it doesn't look like they have released anything for
  11. Solaris yet.  I also haven't had a chance to test the patch yet. 
  12. Here is a bit from the new patch:
  13.  
  14.     Patch-ID# 101080-01
  15.     Keywords: CTE5592, ex, security, vi, expreserve
  16.     Synopsis: SunOS 4.1.1 4.1.2 4.1.3: security problem with expreserve
  17.     Date: Jun/09/93
  18.     ...
  19.     SunOS release: 4.1.1 4.1.2 4.1.3
  20.     ...
  21.     Problem Description: 
  22.     1044909    race condition when file is created owned by root.
  23.     1083183    expreserve can be used to overwite any file.
  24.      
  25.  
  26. So, because the hole seems to still need to be fixed in Solaris,
  27. I am sending around updates to the patches that I sent previously.
  28. Some very sharp people around the world pointed out problems in the
  29. patches that I sent previously, and correspondingly updated versions
  30. appear below.  Oh yeah, and I added a detailed discussion of how you
  31. can become root.  Should have put that in last time, sorry.
  32.  
  33. Thanks for your time.  This message may be freely redistributed.
  34.  
  35. chris...
  36. -----------------
  37.  
  38. Subject: bug in expreserve/security hole/fixes attached
  39.  
  40. PATCH ID:  101080-01
  41. The patch is ONLY available for SunOS 4.1.?
  42.  
  43. OVERVIEW:
  44. A bug in the program /usr/lib/expreserve, a standard program delivered 
  45. with SunOS and setuid root, opens a huge security hole.  Using this
  46. program as delivered, any user can overwrite any file in the system
  47. with no effort and can become root with some cracking skills.  Fixes
  48. are given below for people with and without source code.
  49.  
  50. AFFECTED SYSTEMS:
  51. SunOS 4, Solaris 2.1, Solaris 2.2, and Sun derivatives like Solbourne.
  52.  
  53. Note: It seems that this bug stems from changes which Sun made to BSD's
  54. expreserve program, and that this hole is therefore restricted to SunOS
  55. and derivatives.  I have confirmation that this hole affects SunOS 4.1.*
  56. and the Solarises.  In Solaris 2.1, expreserve is not setuid but I am
  57. told that the bug is still there, making an indirect attack possible -
  58. see below.  Solaris 2.2 is also affected; expreserve is set-uid root in
  59. that release.  No word yet on releases prior to SunOS4.  
  60.  
  61. HISTORY:
  62. This bug was recently published in ``iX'' (a German magazine for UNIX 
  63. and related issues, June 1993, pp. 170-171).  One person reports
  64. hearing of this problem in 1987.  People have mailed me to say that
  65. they reported this bug to Sun in 1991 and 1992, so it's clearly not
  66. new to Sun.  I think it is safe to say that this problem is now well
  67. known.
  68.  
  69. WHAT IS EXPRESERVE:
  70. The expreserve program is invoked by the editor ``vi'' if the editor
  71. session is killed (e.g., by stopping the editor with ctrl-Z and then
  72. logging out).  The contents of the editor buffer are copied from
  73. the file ``/var/tmp/ExNNNNN'' and written into a file by the name of 
  74. ``/var/preserve/USER/ExaaaNNNNN'' (where N is a decimal digit).  The
  75. expreserve program is also invoked at boot time to recover any saved
  76. editor sessions which are in /var/tmp at boot time; the assumption is
  77. that the editor was killed by a system crash. 
  78.  
  79. THE BUG:
  80. The security hole is caused by a bug in expreserve rather than an
  81. oversight.  Expreserve attempts to check for existence of the file in
  82. which it wants to write a saved editor session, but it uses an incorrect
  83. path name (which happens to begin with the slash character) instead of
  84. the correct, absolute path name.  Therefore the check always succeeds
  85. (no clash is ever detected) and expreserve happily blasts away using the
  86. correct file name.  The bug can be exploited by creating links to real
  87. system files and then triggering the expreserve program.
  88.  
  89. TESTING YOUR VERSION OF EXPRESERVE:
  90. Start vi and type in a few lines - enough so that the program creates a
  91. /var/tmp/ExNNNNN file.  Stop the editor with ctrl-Z.  As *root*, issue this
  92. command: ``trace /usr/lib/expreserve -a |& grep stat'' and look at the
  93. output.  If the bug is present, you will see a line something like this:
  94.     stat ("/Exaaa09466", 0xf7fff4a0) = -1 ENOENT (No such file or directory)
  95. I.e., the program looks in root.  If the line looks something like this:
  96.     stat ("/var/preserve/USER/Exaaa09466", 0xf7fff4a0) = -1 ENOENT ....
  97. then your version is not affected by this bug.
  98.  
  99. A PATCH THAT DOESN'T:
  100. According to my test (above), Sun's Patch nr. 100251-01 does not correct
  101. the problem.
  102.  
  103. HOW TO BECOME ROOT:
  104. The trick is to overwrite /etc/passwd with a dummy entry for uid 0.
  105. Since ex doesn't store newlines in the text as newlines in the save
  106. file, we have to kludge a bit and tell ex to edit a _file_ called
  107.     ``\n\nroot::0:1:cracker:/:/bin:sh\n+::0:0:::\n\n''
  108. (Notice the line to include NIS passwd information as well.  If you
  109. only have an entry for root, then su doesn't work and you can only
  110. become root if you have access to the console, assuming that root
  111. logins on pseudo-ttys are blocked.)  Then we suspend ex and figure out
  112. its pid (1045 say) and the highest used pid (1047 say). With a bit of
  113. luck and timing, the expreserve process we'll force will have pid
  114. 1047+2 = 1049.  Then ``ln -s /etc/passwd /var/preserve/<yourname>/Exaaa01049''
  115. and kill -10 1045. (/var/preserve/<yourname> must exist; you can easily
  116. construct it by running ex two times.)  This will make ex spawn off
  117. expreserve and make it dump the file name and contents in the file
  118. .../Exaaa01049, i.e. /etc/passwd. 
  119.  
  120. THE SOLARIS 2.1 TWIST:
  121. Actually, this attack succeeds on all affected systems, but seems
  122. to be the only way to attack Solaris 2.1.  Assuming that the scenario
  123. works with (symbolic) links in /var/preserve/<user>, a user only has
  124. to make a number of links in his /var/preserve/<user> directory with
  125. numbers that are low enough to occur when expreserve is run at reboot,
  126. dump some editor buffers in /var/tmp and wait until the next reboot.
  127. Of course, if the machine is accessible, the user can just pull the
  128. plug and force a reboot that way.
  129.  
  130. A FIX (NO SOURCE REQUIRED):
  131. The following procedure closes the security holes, including the one
  132. in solaris 2.1.  The first two commands turn off the setuid bits on the
  133. critical programs.  Then /var/preserve is opened up so that expreserve
  134. can create directories for users (the only reason why it was setuid root).
  135. Next, a directory is created for root to avoid trojan-horse attacks -
  136. a user could create lots of links in root's directory and wait for
  137. root to kill an editor session.  Unlikely but possible.  Finally, a
  138. check is added to /etc/rc?? to prevent reboot-style attacks.
  139.  
  140.         chmod u-s /usr/lib/expreserve
  141.         chmod u-s /usr/lib/exrecover
  142.         chmod 1777 /var/preserve
  143.         mkdir /var/preserve/root
  144.         chmod 700 /var/preserve/root
  145.         touch /var/preserve/root/.do-not-delete-me 
  146.  
  147. Finally, the following command must be executed at boot-time BEFORE
  148. expreserve is invoked:
  149.     /usr/bin/find /var/preserve '(' ! -type d ! -type f -o \
  150.         -type f -links +1 ')' -exec /bin/rm {} ';'
  151.  
  152. A GOOD FIX (SOURCE REQUIRED):
  153. No, I don't know where you can get source to expreserve.  We have
  154. sources from Sun.  The following patch fixes the bug.  The first
  155. change is to call the mknext() function with the correct buffer -
  156. the one in which the entire name of the prospective saved-session
  157. file is stored, not just the last component.  The second change alters
  158. the call to stat() in mknext() to be a call to lstat().  This prevents
  159. users from creating garbage files in otherwise unwritable system
  160. directories by creating and exploiting a link to a nonexistent file.
  161. For example, a user could create a crontab file for daemon, etc.
  162.  
  163. Note that my version of expreserve.c seems to be from 4.1.1.  In that
  164. version, the target output file is creat()'ed immediately after a call
  165. to ``close(1)'' thereby guaranteeing that the new fd is 1.  Some changes
  166. were made in 4.1.3, namely that the file is created using the statement
  167. ``if ((savfild=creat(savfil, 0600)) < 0) {'' and then the file descriptor
  168. is used in later operations instead of assuming file descriptor 1. 
  169. I believe this is the race condition alluded to in Sun's patches of
  170. expreserve.  Laura Pearlman suggests changing the creat() to an open():
  171. ``if ((savfild=open(savfil, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) {''
  172. because this guarantees that no determined cracker can slip in a link
  173. in that directory between the mknext() and the creat().  Because I
  174. do not have the 4.1.3 source, I cannot distribute a reliable patch
  175. that incorporates this knowledge.
  176.  
  177. Apply the patch to the file expreserve.c (in directory .../usr.bin/ex),
  178. recompile, relink, and install the program.  It appears to be safe
  179. to leave the setuid bit on once this patch has been applied, but I
  180. can NOT guarantee that this patch fixes all problems with expreserve. 
  181.  
  182. --snip--
  183. *** expreserve.c.orig    Fri May 28 08:36:51 1993
  184. --- expreserve.c    Wed Jun  9 20:55:06 1993
  185. ***************
  186. *** 271,281 ****
  187.       }
  188.   
  189.       /*
  190. -      * File is good.  Get a name and create a file for the copy.
  191. -      */
  192. -     mknext(pattern);
  193. -     (void) close(1);
  194. -     /*
  195.        * See if preservation directory for user exists.
  196.        */
  197.       
  198. --- 271,276 ----
  199. ***************
  200. *** 299,304 ****
  201. --- 294,306 ----
  202.       }
  203.       strcpy (savfil, savdir);
  204.       strcat(savfil, pattern);
  205. +     /*
  206. +      * File is good.  Get a name and create a file for the copy.
  207. +      */
  208. +     mknext(savfil);
  209. +     (void) close(1);
  210.       if (creat(savfil, 0600) < 0) {
  211.           if (name == 0)
  212.               perror(savfil);
  213. ***************
  214. *** 378,384 ****
  215.               dcp[-1]++;
  216.       } else
  217.           dcp[0]++;
  218. !     if (stat(cp, &stb) == 0)
  219.           goto whoops;
  220.   }
  221.   
  222. --- 380,386 ----
  223.               dcp[-1]++;
  224.       } else
  225.           dcp[0]++;
  226. !     if (lstat(cp, &stb) == 0)
  227.           goto whoops;
  228.   }
  229.   
  230. --snip--
  231.  
  232. A RELATED PROBLEM:
  233. The /etc/rc file as delivered with SunOS 4.1.1 issues this command
  234. to save editor sessions: ``(cd /tmp; /usr/lib/expreserve -a)''
  235. However, the editors use /var/tmp.  For those who have separate /tmp
  236. and /var/tmp directories (for example, /tmp as a ram disk), then any
  237. vi session files are never recovered at boot-time.  In our setup, /tmp
  238. is just a link to /var/tmp, so this hasn't bitten us.
  239.  
  240. A BETTER SOLUTION?
  241. Mr Ellis of CERT suggests that the best solution is to simply give up
  242. root privileges after creating the directory for the user.  I have not
  243. tried to figure out the consequences of this one.  Perhaps Sun will
  244. consider this in their work.
  245.  
  246. FINAL COMMENT:
  247. I think the practice of creating a /var/preserve/USER directory is poor. 
  248. Any user can do this and can then happily instigate a denial of service
  249. attack by filling the corresponding partition to 100%. (I suppose that
  250. the saving of editor files would still work in that situation, since root
  251. does the writing, but it's still very unclean.)  Why not just leave files
  252. under /var/expreserve?  The name creation has 26^3 possibilities (aaa, aab,
  253. etc.) so clashing names for a given process ID shouldn't be a problem.
  254.  
  255. CREDITS:
  256. Many thanks to the following people:
  257.     Heinrich Welter (author of the article in iX)
  258.     Paul Kurzweil <kurzweil@informatik.uni-kl.de>,
  259.     Alfred Broeckers <broecker@informatik.uni-kl.de>,
  260.     Mikael Pettersson <mpe@ida.liu.se>,
  261.     Klaus-Peter Kossakow <kossakow@rzdspc5.informatik.uni-hamburg.de>,
  262.     Casper Dik <casper@fwi.uva.nl>,
  263.     Daniel Trinkle <trinkle@cs.purdue.edu>,
  264.     Jim Ellis <jte@cert.org>,
  265.     Wolfgang Rupprecht <wolfgang@wsrcc.com>,
  266.     Laura Pearlman <pearlman@monty.rand.org>
  267.  
  268. ---
  269. "Christopher Lott   lott@informatik.uni-kl.de   +49 (631) 205-3334, -3331 Fax"
  270. "Post: FB Informatik - Bau 57, Universitaet KL, 67653 Kaiserslautern, Germany"
  271.  
  272.